package cn.edu.zsc.rbac.util;

import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SingletonFactory {
    // ⽤于存储 Class对象 与 类单例 之间的映射，采⽤线程安全的ConcurrentHashMap
    private static final Map<Class<?>, Object> instanceMap = new
            ConcurrentHashMap<>();
    /**
     * 单例⼯⼚⽅法，通过反射机制根据传⼊的类类型创建并返回对应类型的单例实例。
     * 如果该类型的实例尚未创建，则会通过反射创建并存储；否则返回缓存中的单例实例。
     *
     * @param clazz 要实例化的类类型，必须有⼀个⽆参构造函数
     * @return 返回指定类型的单例实例
     * @throws IllegalArgumentException 如果传⼊的类型为空，或者反射创建实例时发⽣
    异常
     */
    public static <T> T getInstance(Class<T> clazz) {
        // 如果传⼊的 clazz 为 null，则抛出异常
        if (clazz == null) {
            throw new IllegalArgumentException("未知的类型");
        }
        // 当clazz对应的实例不存在时进⾏创建
        if (!instanceMap.containsKey(clazz)) {
            try {
                // 获取类的⽆参构造函数
                Constructor<T> constructor = clazz.getDeclaredConstructor();
                // 设置构造函数可访问，即使构造函数是私有的也可以使⽤
                constructor.setAccessible(true);
                // 使⽤构造函数实例化对象
                T singleton = constructor.newInstance();
                // 存⼊map
                instanceMap.put(clazz, singleton);
            } catch (Exception e) {
                // 如果反射过程中发⽣异常（如没有⽆参构造函数、实例化失败等），抛出⾃定义异常
                throw new IllegalArgumentException("创建单例模式失败: " + clazz.getSimpleName(), e);
            }
        }
        @SuppressWarnings("unchecked")
        T instance=(T)instanceMap.get(clazz);
        return instance;
    }
}
